package vip.web3.api.service.impl.biz;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Connection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.web3.api.dao.biz.UserDao;
import vip.web3.api.dao.biz.UserWalletDao;
import vip.web3.api.entity.biz.RecordEntity;
import vip.web3.api.entity.biz.UserEntity;
import vip.web3.api.entity.biz.UserWalletEntity;
import vip.web3.api.form.user.RechargeForm;
import vip.web3.api.form.user.TransferForm;
import vip.web3.api.form.user.WithdrawForm;
import vip.web3.api.service.base.SysConfigApiService;
import vip.web3.api.service.biz.RecordService;
import vip.web3.api.service.biz.UserWalletService;
import vip.web3.common.enums.OperateEnum;
import vip.web3.common.enums.WalletTypeEnum;
import vip.web3.common.exception.RRException;
import vip.web3.common.utils.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Service
public class UserWalletServiceImpl extends ServiceImpl<UserWalletDao, UserWalletEntity> implements UserWalletService {

    private static String appid = "fa611651f57959b6f9f34936";

    private static String secret = "41283630109f5Bd63b65e1d63eC9eBe9c00E4100";

    private static String url = "http://quechaotue-api.meisuobudamiya.com/api/order";

    @Resource
    private UserDao userDao;

    @Resource
    private SysConfigApiService sysConfigApiService;

    @Resource
    private RecordService recordService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void transfer(TransferForm form) {
        if (form.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
            throw new RRException("划转金额错误!", -1);
        }
        UserEntity user = this.userDao.selectById(Servlets.getUserId());
        UserWalletEntity wallet = this.lambdaQuery().eq(UserWalletEntity::getUserId, Servlets.getUserId()).one();
        if(!DigestUtils.sha256Hex(form.getPassword()).equals(user.getFundPassword())){
            throw new RRException("资金密码错误!");
        }
        if (Objects.isNull(user) || Objects.isNull(wallet)) {
            throw new RRException("用户不存在!", -1);
        }

        // 如果二次下单要用原来的钱包type
        WalletTypeEnum transferType = WalletTypeEnum.get(form.getType());
        WalletTypeEnum walletType = WalletTypeEnum.get(wallet.getType());

        if (WalletTypeEnum.USDT.equals(walletType) && !WalletTypeEnum.USDT.equals(transferType)) {
            throw new RRException("您只能划转USDT!", -1);
        }

        RecordEntity entity = new RecordEntity();
        if (WalletTypeEnum.CNY.equals(walletType) || WalletTypeEnum.UNKNOWN.equals(walletType)) {
            if (form.getAmount().compareTo(wallet.getWithdrawCny()) > 0) {
                throw new RRException("可用余额不足!", -1);
            }
            int updated = this.baseMapper.updateMixCny(wallet.getId(), form.getAmount(), form.getAmount().negate(), wallet.getVersion());
            if (updated < 1) {
                throw new RRException("划转失败,稍后再试!", -1);
            }
            if (WalletTypeEnum.UNKNOWN.equals(walletType)){
                wallet = this.lambdaQuery().eq(UserWalletEntity::getUserId, Servlets.getUserId()).one();
                wallet.setType(WalletTypeEnum.CNY.getCode());
                baseMapper.updateById(wallet);
            }
            entity.setOperateType(1);
        }
        if (WalletTypeEnum.USDT.equals(walletType)) {
            if (form.getAmount().compareTo(wallet.getWithdrawUsdt()) > 0) {
                throw new RRException("可用余额不足!", -1);
            }
            int updated = this.baseMapper.updateMixUsdt(wallet.getId(), form.getAmount(), form.getAmount().negate(), wallet.getVersion());
            if (updated < 1) {
                throw new RRException("划转失败,稍后再试!", -1);
            }
            entity.setOperateType(2);
        }
        // 添加记录
        entity.setUserId(user.getId());
        entity.setMobile(user.getMobile());
        entity.setType(OperateEnum.TYPE3.getType());
        entity.setTypeName(OperateEnum.TYPE3.getMark());
        entity.setRemark(OperateEnum.TYPE3.getDesc());
        entity.setAmount(form.getAmount());
        entity.setFee(BigDecimal.ZERO);
        entity.setStatus(1);
        entity.setCreateDate(new Date());
        entity.setUpdateDate(new Date());
        recordService.save(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void recharge(RechargeForm form) {
        JSONObject map = new JSONObject();
        map.put("app_id", appid);
        map.put("product_id", 6 +"");
        String code = SnowFlakeUtil.nextId() + "";
        map.put("out_trade_no", code);
        map.put("notify_url", "http://47.121.187.203:8057/base/api/asset/recharge/notify");
        map.put("amount", "102");
        Long time = System.currentTimeMillis()/ 1000L;
        map.put("time", time +"");
//        map.put("desc", code);

        String md5_ = "amount=102" +
                        "&app_id=" + appid +
                        "&notify_url=http://47.121.187.203:8057/base/api/asset/recharge/notify" +
                        "&out_trade_no=" + code +
                        "&product_id=6" +
                        "&time=" + time +
                        "&key=" + secret;
        String md5 = SignUtils.md5Password(md5_);
        map.put("sign", md5.toLowerCase());
        System.out.println(md5_);
        System.out.println(md5);
        System.out.println(map.toString());

        Map<String, String> header = new HashMap<>();
        header.put("Content-Type", "application/json");
        try{
            Connection.Response post = VeryPowerHttpUtils.post(url, header, map.toString());
            String body = post.body();
            System.out.println(body);
        }catch (Exception ex){

        }
    }

    @Override
    public void withdraw(WithdrawForm form) {
        UserEntity user = this.userDao.selectById(Servlets.getUserId());
        if(user.getAuthStatus().intValue() != 3){
            throw new RRException("请先进行实名认证!");
        }
        UserWalletEntity wallet = this.lambdaQuery().eq(UserWalletEntity::getUserId, Servlets.getUserId()).one();
        if(!DigestUtils.sha256Hex(form.getPassword()).equals(user.getFundPassword())){
            throw new RRException("资金密码错误!");
        }
        if (Objects.isNull(user) || Objects.isNull(wallet)) {
            throw new RRException("用户不存在!", -1);
        }
        if(form.getType().intValue() == 1){
            boolean withdraw = false;
            try {
                String start = sysConfigApiService.getValue("withdraw:cny:limit:start");
                String end = sysConfigApiService.getValue("withdraw:cny:limit:end");
                Date date = new Date();
                String format = DateUtils.format(date, DateUtils.DATE_PATTERN);
                if (StringUtils.isBlank(start)){
                    start = "09:00:00";
                }
                if (StringUtils.isBlank(end)){
                    end = "18:00:00";
                }
                Date startTime = DateUtils.parse(format + " " + start, DateUtils.DATE_TIME_PATTERN);
                Date endTime = DateUtils.parse(format + " " + end, DateUtils.DATE_TIME_PATTERN);
                if(date.getTime() > endTime.getTime() || date.getTime() < startTime.getTime()){
                    withdraw = true;
                }
            } catch (Exception ex){}

            if (withdraw) {
                throw new RRException("非提现时间!", -1);
            }
            if (form.getAmount().compareTo(wallet.getWithdrawCny()) > 0) {
                throw new RRException("可用余额不足!", -1);
            }
            if (!form.getRealName().equals(user.getRealName())) {
                throw new RRException("实名信息异常!", -1);
            }
            String cnyLimit = sysConfigApiService.getValue("withdraw:cny:limit");
            if (form.getAmount().compareTo(new BigDecimal(cnyLimit)) < 0) {
                throw new RRException("最小提现金额:" + cnyLimit, -1);
            }

            int updated = this.baseMapper.updateWithdrawCny(wallet.getId(), form.getAmount().negate(), wallet.getVersion());
            if (updated < 1) {
                throw new RRException("提现失败,稍后再试!", -1);
            }
            // 添加记录
            RecordEntity entity = new RecordEntity();
            entity.setUserId(user.getId());
            entity.setMobile(user.getMobile());
            entity.setType(OperateEnum.TYPE2.getType());
            entity.setTypeName(OperateEnum.TYPE2.getMark());
            entity.setRemark(OperateEnum.TYPE2.getDesc());
            entity.setAmount(form.getAmount());
            entity.setFee(BigDecimal.ZERO);
            entity.setOperateType(form.getType());
            entity.setBankName(form.getBankName());
            entity.setBankNum(form.getBankNum());
            entity.setRealName(form.getRealName());
            entity.setStatus(0);
            entity.setCreateDate(new Date());
            entity.setUpdateDate(new Date());
            recordService.save(entity);
        } else if (form.getType().intValue() == 2 || form.getType().intValue() == 3) {
            if (form.getAmount().compareTo(wallet.getWithdrawUsdt()) > 0) {
                throw new RRException("可用余额不足!", -1);
            }
            String usdtLimit = sysConfigApiService.getValue("withdraw:usdt:limit");
            String fee = sysConfigApiService.getValue("withdraw:usdt:fee");
            if (form.getAmount().compareTo(new BigDecimal(usdtLimit)) < 0) {
                throw new RRException("最小提现金额:" + usdtLimit, -1);
            }
            int updated = this.baseMapper.updateWithdrawUsdt(wallet.getId(), form.getAmount().negate(), wallet.getVersion());
            if (updated < 1) {
                throw new RRException("提现失败,稍后再试!", -1);
            }
            // 添加记录
            RecordEntity entity = new RecordEntity();
            entity.setUserId(user.getId());
            entity.setMobile(user.getMobile());
            entity.setType(OperateEnum.TYPE2.getType());
            entity.setTypeName(OperateEnum.TYPE2.getMark());

            entity.setRemark(OperateEnum.TYPE2.getDesc());
            entity.setAmount(form.getAmount());
            entity.setFee(new BigDecimal(fee));
            entity.setOperateType(form.getType());
            entity.setStatus(0);
            entity.setAddress(form.getAddress());
            entity.setCreateDate(new Date());
            entity.setUpdateDate(new Date());
            recordService.save(entity);
        }
    }

    public static void main(String[] args) {
        String s = SignUtils.md5Password("amount=100&app_id=123456&notify_url=http://my_notify_url&out_trade_no=202001016447" +
                "&product_id=16&time=1500001234&key=abcdefg");

        System.out.println(s.toLowerCase());

        boolean withdraw = false;
        try {
            String start = "";
            String end =  "";
            Date date = new Date();
            String format = DateUtils.format(date, DateUtils.DATE_PATTERN);
            if (StringUtils.isBlank(start)){
                start = "00:00:00";
            }
            if (StringUtils.isBlank(end)){
                end = "18:00:00";
            }
            Date startTime = DateUtils.parse(format + " " + start, DateUtils.DATE_TIME_PATTERN);
            Date endTime = DateUtils.parse(format + " " + end, DateUtils.DATE_TIME_PATTERN);
            if(date.getTime() > endTime.getTime() || date.getTime() < startTime.getTime()){
                withdraw = true;
            }
            System.out.println(withdraw ? "非提现时间" : "提现时间");
        } catch (Exception ex){}
    }

}
